/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.common.utils.web;

import java.util.Locale;

import org.springframework.util.StringUtils;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * xxx
 *
 * @author Wangyi
 * @version v1.0
 *
 * @date 2013-9-22
 *
 */
public class QueryOrder {
	
	public static final Direction DEFAULT_DIRECTION = Direction.ASC;
	
	@JsonProperty("dir")
	private final Direction direction;
	@JsonProperty("prop")
	private final String property;

	/**
	 * Enumeration for sort directions.
	 * 
	 * @author Oliver Gierke
	 */
	public static enum Direction {

		ASC, DESC;

		/**
		 * Returns the {@link Direction} enum for the given {@link String} value.
		 * 
		 * @param value
		 * @return
		 */
		public static Direction fromString(String value) {

			try {
				return Direction.valueOf(value.toUpperCase(Locale.US));
			} catch (Exception e) {
				throw new IllegalArgumentException(String.format(
						"Invalid value '%s' for orders given! Has to be either 'desc' or 'asc' (case insensitive).", value), e);
			}
		}
	}
	
	@JsonCreator
	public QueryOrder(@JsonProperty("dir") Direction direction, @JsonProperty("prop") String property) {

		if (!StringUtils.hasText(property)) {
			throw new IllegalArgumentException("Property must not null or empty!");
		}

		this.direction = direction == null ? DEFAULT_DIRECTION : direction;
		this.property = property;
	}
	
	/**
	 * Returns the order the property shall be sorted for.
	 * 
	 * @return
	 */
	public Direction getDirection() {
		return direction;
	}

	/**
	 * Returns the property to order for.
	 * 
	 * @return
	 */
	public String getProperty() {
		return property;
	}

	/**
	 * Returns whether sorting for this property shall be ascending.
	 * 
	 * @return
	 */
	@JsonIgnore
	public boolean isAscending() {
		return this.direction.equals(Direction.ASC);
	}
	
	public QueryOrder with(Direction order) {
		return new QueryOrder(order, this.property);
	}
	
}
